/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Arrow_Topic_h
#define SBJ_Arrow_Topic_h

#include <boost/logic/tribool.hpp>

#include <string>

namespace SBJ
{

namespace Arrow
{

class Message;
class Publication;
class MsgProxy;
class TopicEntry;

/*
	Topic is
	
	A Topic has three states
	Invalid: the topic cannot be used inside of a message
	Empty: the topic has both a message handler and publication but no topic
	Subscribed: the topic is valid and not empty.
	
	Motivation:
	
*/

class Topic
{
public:	
	struct SharedData
	{
		SharedData( const MsgProxy* msgHnd, const std::string& topicKey )
		: msgProxy( msgHnd ), key( topicKey ), use( 0 ) {}
		const MsgProxy* msgProxy;
		std::string key;
		volatile mutable int use; // needs to be atomic
		size_t hash;
	};
	
	static const std::string emptyKey;
	
	inline Topic( void );
	
	inline Topic( const Topic& rhs );

	inline Topic& operator = ( const Topic& rhs );

	inline operator size_t () const;
	
	inline bool operator < ( const Topic& rhs ) const;
	
	inline bool operator == ( const Topic& rhs ) const;
	
	inline bool isEmpty( void ) const;
	
	inline bool isValid( void ) const;
	
	inline const MsgProxy& getMsgProxy( void ) const;
	
	inline bool isSameMsgType( const Topic& rhs ) const;
	
	inline boost::tribool hasSubscription( void ) const;
	
	const std::string& getPublicationKey( void ) const;
	
	inline const std::string& getTopicKey( void ) const;
	
	inline void addUse( void ) const;
	
	inline void removeUse( void ) const;
	
private:
	friend class Publication;
	
	inline Topic( const Publication* publication, const MsgProxy* MsgProxy );
	
	inline Topic( const Publication* publication, SharedData* shared );
	
	const Publication* m_publication;
	const MsgProxy* m_msgProxy;
	SharedData* m_shared;
	size_t m_hash;
};

}

}

#include "SBJ/Arrow/Topic.inl"

#endif